package csp;

import java.util.StringTokenizer;

/**
 *clase principal del analizador sintactico predictivo.
 * <ul>
 * <li>prog→conjprods</li>
 * <li>conjprods→conjprods | prod</li>
 * <li>prod→variable DEF expr</li>
 * <li>expr→expr ALT term | term</li>
 * <li>term→term & factor | factor</li>
 * <li>factor→{expr} | [expr] | primario</li>
 * <li>primario→{expr} | variable | termina</li>
 * <li></li>
 * <li></li>
 * </ul>
 * 
 * @author Larissa Gabriela Bolívar Vzqz
 * @version 1.0
 * @since 19/03/2015
 */

public class Csp {

    private static final int FIN_PRODUCCION = ';';
    private static final int CONCATENACION = '&';
    private static final int ALTERNACION = '|';
    private static final int LLAVE_DER = '}';
    private static final int LLAVE_IZQ = '{';
    private static final int DEFINICION = '=';
    private static final int FIN_ARCHIVO = '.';
    private static final int VAR = 2;
    
    private Integer linea = 1;
    private StringTokenizer tokenizer = null;
    
    
    private StringTokenizer gettTokenizer(String codigoFuente){
        if(this.tokenizer == null){
            //;+-*/()
            String alfabeto = String.format("%s%s%s%s%s%s%s",
                    (char) FIN_PRODUCCION, (char) CONCATENACION,(char)ALTERNACION,
                    (char)LLAVE_DER, (char)LLAVE_IZQ,(char)DEFINICION,
                    (char)FIN_ARCHIVO);
            this.tokenizer = new StringTokenizer(codigoFuente.trim(),alfabeto,true);
        }
        return tokenizer;
    }
    
    private Token lex(String codigoFuente){
        Token token=null;
        
        String currentToken = this.gettTokenizer(codigoFuente).nextToken();
         if(esNumero(currentToken)){
             token = new Token(this.linea, VAR, currentToken);
         }else{
           int tokenSimple = currentToken.charAt(0);
           switch(tokenSimple){
               case FIN_PRODUCCION:
               linea++;
               token=new Token(this.linea,FIN_PRODUCCION, String.format("%s", 
                       (char)tokenSimple));
                   break;
                   
                   case CONCATENACION:
               linea++;
               token=new Token(this.linea,CONCATENACION, String.format("%s", 
                       (char)tokenSimple));
                   break;
                   
               case ALTERNACION:
               linea++;
               token=new Token(this.linea,ALTERNACION, String.format("%s", 
                       (char)tokenSimple));
                   break;
                   
               case LLAVE_DER:
               linea++;
               token = new Token(this.linea,LLAVE_DER, String.format("%s", 
                       (char)tokenSimple));
                   break;
                   
                case LLAVE_IZQ:
               linea++;
               token = new Token(this.linea,LLAVE_IZQ, String.format("%s", 
                       (char)tokenSimple));
                   break;
                    
                case DEFINICION:
               linea++;
               token = new Token(this.linea,DEFINICION, String.format("%s", 
                       (char)tokenSimple));
                   break;
                    
                    case FIN_ARCHIVO:
               linea++;
               token = new Token(this.linea,FIN_ARCHIVO, String.format("%s", 
                       (char)tokenSimple));
                   break;
                   default:
                        throw new Error("ERROR de lexico: "
                            +"el caracter no esta dentro del alfabeto");
            }
           }
        return token;
    }
    
    
    
     public static Boolean esNumero(String textorevisar){
         Boolean esNumero = true;
         for (int  i = 0;  i < textorevisar.length();  i++) {
             esNumero = esNumero &&
                     Character.isDigit(textorevisar.charAt(i));
         }
        return esNumero;
     }
     
    public static void main(String[] args) {
        Csp analizador = new Csp();
        while (analizador.gettTokenizer("{8}").hasMoreTokens()) {
            Token t = analizador.lex("");
            System.out.println(t);    
        }
    } 
}
